Skip to content

feat(trade): add attached order (take-profit/stop-loss) support - #549

Merged
sunli829 merged 11 commits into
mainfrom
feat/attached-orders
Jul 29, 2026
Merged

feat(trade): add attached order (take-profit/stop-loss) support#549
sunli829 merged 11 commits into
mainfrom
feat/attached-orders

Conversation

@sunli829

@sunli829 sunli829 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add attached order (take-profit / stop-loss) support across all language SDKs (Rust, Python, Node.js, Java, C, C++)

Added

  • New types: AttachedOrderType (ProfitTaker / StopLoss / Bracket), AttachedOrderDetail, SubmitAttachedParams, ReplaceAttachedParams
  • SubmitOrderOptions / ReplaceOrderOptions: new attached_params field
  • Order / OrderDetail: new attached_orders field
  • New order_detail_attached(order_id) method — queries detail for an attached sub-order by its own ID
  • GetTodayOrdersOptions: new is_attached flag — when combined with order_id, tells the server to treat order_id as an attached sub-order ID; returns that sub-order as an Order entry (not the parent)

Breaking changes

  • OrderDetail.charge_detail is now Option<OrderChargeDetail> — attached orders return null for this field; callers must handle the absent case
  • C SDK: lb_order_detail_t gains a new has_charge_detail: bool field before charge_detail; ABI changed, recompile required

Test plan

  • All 6 language SDKs tested end-to-end against openapi.longbridge.xyz
  • 6 parameter combinations: ProfitTaker only, StopLoss only, Bracket, Bracket with limit prices, Bracket with activate order type, Bracket with GTC time-in-force
  • is_attached semantics verified against live API

🤖 Generated with Claude Code

sunli829 added 9 commits July 22, 2026 17:11
Add attached order API support across all language SDKs based on
developers PR #1092.

New types:
- AttachedOrderType enum (ProfitTaker / StopLoss / Bracket)
- AttachedOrderDetail response struct
- SubmitAttachedParams / ReplaceAttachedParams request builders
- GetOrderDetailOptions (with is_attached flag)

API changes (non-breaking):
- Order / OrderDetail: new attached_orders field
- SubmitOrderOptions: new attached_params builder
- ReplaceOrderOptions: new attached_params builder
- GetTodayOrdersOptions: new is_attached() flag
- order_detail: accepts impl Into<GetOrderDetailOptions>
- New order_detail_attached method (Rust/Python/Node.js/Java/C/C++)
Bugs fixed:
- AttachedOrderType serialized as "Bracket" instead of "BRACKET" — switched
  from #[derive(Serialize)] to impl_serde_for_enum_string! to use strum Display
- SubmitOrderOptions.expire_date serialized as null when absent — added
  skip_serializing_if = "Option::is_none"
- AttachedOrderDetail.attached_type_display was i32, now AttachedOrderType
- AttachedOrderDetail.trigger_status was i32, now Option<TriggerStatus>
- AttachedOrderDetail.tag was i32, now OrderTag
- AttachedOrderDetail.executed_price was Decimal, now Option<Decimal>
- OrderDetail.charge_detail was non-optional, now Option<OrderChargeDetail>
  (C SDK: added has_charge_detail bool flag)
- Java SdkNative.tradeContextOrderDetailAttached missing public modifier

Add AttachedOrderType::Unknown variant across all language bindings.
Add submit_order_with_attached examples for all languages.
Update CLAUDE.md: python/pyproject.toml uses dynamic = ["version"].
…nd GetOrderDetailOptions

is_attached=true indicates that the provided order_id is an attached
sub-order ID, not a regular order ID. It does not filter results to
show only attached orders.
is_attached=true only takes effect when combined with order_id.
It tells the server to treat order_id as an attached sub-order ID
for lookup. Without order_id it has no effect and does NOT filter
results to show only attached orders.
…rent

Based on actual API testing: today_orders(order_id=attached_id, is_attached=True)
returns the attached sub-order as an Order entry with its own order_id,
side, order_type etc — not the parent order.
Rebasing feat/attached-orders onto main required merging attached-order
changes with the US market APIs / client_request_id features; the naive
git merge left nodejs/index.d.ts with duplicate US-market method
declarations (no conflict markers, just misaligned content). Rebuilding
with napi and rustfmt brings the generated files back in sync with the
Rust source.
The withdraw endpoint gained an optional is_attached flag (per
developers PR #1092) so a take-profit/stop-loss sub-order can be
cancelled by its own order ID. Wired non-breakingly per language:
Rust CancelOrderOptions (impl Into<T>, backward-compatible via
From<&str>/From<String>), Python is_attached kwarg, Node.js optional
isAttached param, C++ defaulted parameter, Java cancelOrder overload,
and a new C lb_trade_context_cancel_order_attached symbol.
@sunli829
sunli829 force-pushed the feat/attached-orders branch from 90a9684 to 2449171 Compare July 22, 2026 09:13
sunli829 and others added 2 commits July 29, 2026 16:41
The napi artifacts command requires pre-built .node binaries for all
configured targets, so it always fails in per-platform CI jobs that only
produce their own binary. Remove the Move artifacts and List packages
steps — they belong in the release workflow, not the CI check.

Also drop two unused imports left over from earlier commits:
QueryUSOrdersOptions (nodejs/src/trade/context.rs) and
GetAllExecutionsOptions (nodejs/src/trade/requests/mod.rs).
@sunli829
sunli829 marked this pull request as ready for review July 29, 2026 09:26
@sunli829
sunli829 merged commit 39d1d4f into main Jul 29, 2026
56 checks passed
@sunli829
sunli829 deleted the feat/attached-orders branch July 29, 2026 09:26
sunli829 added a commit to longbridge/openapi-go that referenced this pull request Jul 29, 2026
## Summary

Ports the attached order (take-profit / stop-loss) feature added to the
Rust/Python/Node.js/Java/C/C++ SDKs in
[longbridge/openapi#549](longbridge/openapi#549)
(docs:
[longbridge/developers#1092](longbridge/developers#1092)).
PR #549 is still open/unmerged upstream at the time of this PR.

- New types: `AttachedOrderType` (`ProfitTaker` / `StopLoss` /
`Bracket`), `AttachedOrderDetail`, `SubmitAttachedParams`,
`ReplaceAttachedParams`
- `SubmitOrder` / `ReplaceOrder`: new `AttachedParams` field
- `Order` / `OrderDetail`: new `AttachedOrders []AttachedOrderDetail`
field
- New `TradeContext.OrderDetailAttached(orderId)` /
`CancelOrderAttached(orderId)` methods — query/cancel an attached
sub-order by its own order ID. Added as separate methods rather than
changing `OrderDetail`/`CancelOrder`'s existing signatures, since Go has
no method overloading or default parameters (other SDKs did this via
optional/default params or `impl Into<Options>`; Go's closest precedent
is the C SDK's separate `lb_trade_context_cancel_order_attached`
function).
- `GetTodayOrders`: new `OrderId` and `IsAttached` fields (`OrderId` was
previously missing entirely even though the API already supported it) —
combined, treats `OrderId` as an attached sub-order ID and returns that
sub-order as an `Order` entry
- New example: `examples/submit_order_with_attached`

## Breaking change

`OrderDetail.ChargeDetail` is now `*OrderChargeDetail` (was a value
type), since the server returns `null` for this field on attached
sub-orders. Matches the same breaking change made upstream across all 6
languages.

## Note for reviewers

`AttachedOrderDetail`'s `AttachedTypeDisplay`, `TriggerStatus`, and
`Tag` fields are implemented as typed string enums (e.g.
`"PROFIT_TAKER"`, `"DEACTIVE"`, `"Normal"`), matching the upstream Rust
struct definitions (tested end-to-end per PR #549's description).
However, the `longbridge/developers` docs PR's JSON example shows these
same three fields as raw integers instead. Since both source PRs are
still open/unreviewed, this is unconfirmed against a live API response —
if the wire format turns out to be numeric, JSON unmarshaling of these
three fields will fail. Worth verifying against a real sandbox response
before this ships.

## Test plan

- [x] `go build ./...` and `go vet ./trade/...`
- [x] Verified the `jinzhu/copier`-based JSON→domain-type conversion
(nested pointer structs, slices of new struct types, nil-safety for
`ChargeDetail`/`AttachedParams`) via a temporary round-trip test, since
this doesn't touch live credentials
- [x] `examples/submit_order_with_attached` builds and vets cleanly in
the `examples` module
- [ ] Not tested against a live API response (no sandbox credentials in
this session)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant